/**
  ******************************************************************************
  * @file    fsm_event_processor.c
  * @author  ashuai0110
  * @version V2.4
  * @date    2024-09-10
  * @brief   有限状态机FSM(参考QP的FSM)
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  * Change Logs:
  * Date          Author        Notes
  * 2024-08-14    ashuai0110    完成基本内容
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "fsm_event_processor.h"

/**
 * @addtogroup state_machine
 * @{
 */

/**
 * @defgroup fsm_event_processor fsm_event_processor
 * @{
 */

/* 私有宏定义-----------------------------------------------------------------*/

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/
/**
 * @defgroup fsm_local_variables fsm local variables
 * @{
 */
static const fsm_event_t fsmReservedEvent[FSM_SIG_USER] = { \
    { FSM_SIG_EMPTY }, { FSM_SIG_ENTRY }, { FSM_SIG_EXIT }, { FSM_SIG_INIT } \
}; /*!< FSM保留事件数组 */

/**
 * @}
 */

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/

/**
 * @defgroup fsm_global_functions fsm global functions
 * @{
 */

/**
  * @brief  FSM构造函数
  *
  * @note   FSM对象内部使用此函数进行初始构造,即将stateHandler初始化为初始转换函数
  *
  * @param  _fsm   : FSM实例化对象
  *
  * @param  initFn : FSM初始转换函数
  *
  * @retval None
  */
void fsm_ctor(fsm_t *_fsm, fsm_state_handler_t initFn)
{
    MW_ASSERT_PARAM(IS_VALID_POINTER(_fsm));
    MW_ASSERT_PARAM(IS_VALID_POINTER(initFn));

    _fsm->stateHandler = initFn; /* 初始转换函数 */
}

/**
  * @brief  FSM初始化函数
  *
  * @note   执行此函数会回调FSM对象的初始转换函数,即完成状态机的初始状态转换,应在fsm_eq_init()之后执行
  *
  * @param  _fsm  : FSM实例化对象
  *
  * @param  event : FSM事件
  *
  * @retval None
  */
void fsm_init(fsm_t *_fsm, fsm_event_t const *event)
{
    MW_ASSERT_PARAM(IS_VALID_POINTER(event));

    _fsm->stateHandler(_fsm, event); /* 执行最顶部的初始转换 */
    _fsm->stateHandler(_fsm, &fsmReservedEvent[FSM_SIG_ENTRY]); /* 执行目标状态的进入事件 */
}

/**
  * @brief  FSM派发函数
  *
  * @note   执行此函数会回调FSM对象对应的状态函数,通过参数event派发事件,即通过事件触发状态机处理
  *
  * @param  _fsm  : FSM实例化对象
  *
  * @param  event : FSM事件
  *
  * @retval None
  */
void fsm_dispatch(fsm_t *_fsm, fsm_event_t const *event)
{
    fsm_state_handler_t stateHandlerTmp;
    uint8_t ret;

    stateHandlerTmp = _fsm->stateHandler; /* 保存当前的状态处理函数 */
    ret = stateHandlerTmp(_fsm, event); /* 执行当前的状态处理并记录返回值 */
    /* 需要状态转换 */
    if(FSM_RET_TRAN == ret)
    {
        stateHandlerTmp(_fsm, &fsmReservedEvent[FSM_SIG_EXIT]); /* 执行当前状态的退出事件 */
        _fsm->stateHandler(_fsm, &fsmReservedEvent[FSM_SIG_ENTRY]); /* 执行目标状态的进入事件 */
    }
}

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */
